package com.qr.backend.controller;

import com.qr.backend.entity.RestInfo;
import com.qr.backend.service.AuthorizeService;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpSession;
import jakarta.validation.constraints.Pattern;
import org.hibernate.validator.constraints.Length;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.print.DocFlavor;

/**
 * @author : jinxiaobo
 * @date : 2023年12月21日 10:32:39
 * @description :
 */
//开启springboot-validate的注解验证
@Validated
@RestController
@RequestMapping("/api/auth")
public class AuthorizeServiceController {

    private final String EMAIL_REGEX = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$";
    private final String USER_NAME_REGEX = "^[a-zA-Z0-9\\u4e00-\\u9fa5]+$";

    @Resource
    private AuthorizeService authorizeService;

    /**
     * 发送邮箱验证码
     * @return
     */
    @PostMapping("validateEmail")
    public RestInfo<String> validateEmail(@Pattern (regexp = EMAIL_REGEX)
                                 @RequestParam(value = "email",required = true) String email
                                    ,HttpSession httpSession){
        //校验邮箱是否已经被某个用户持有,如果已经被使用那么就不能使用该邮箱再次注册
        /**
         * 将邮箱地址和sessionId传递过来
         * hasCount表示是否需要有账户才能发送邮件,因为更新密码的时候必须是有账户
         * 但是注册的时候必须是没有账户,通过该字段判断发送验证码要不要校验用户存在
         */
        String result = authorizeService.sendValidateEmail(email,httpSession.getId(),false);
        return RestInfo.success(result);
    }

    /**
     * 发送邮箱验证码,如果是重置密码的话必须要求有账户
     * @return
     */
    @PostMapping("validateResetEmail")
    public RestInfo<String> validateResetEmail(@Pattern (regexp = EMAIL_REGEX)
                                          @RequestParam(value = "email",required = true) String email
            ,HttpSession httpSession){
        String result = authorizeService.sendValidateEmail(email,httpSession.getId(),true);
        return RestInfo.success(result);
    }


    /**
     * 注册用户
     * @return
     */
    @PostMapping("register")
    public RestInfo<String> register(@Pattern(regexp = USER_NAME_REGEX) @Length(min = 2,max = 8) @RequestParam("username") String username,
                                     @Length(min = 8,max = 16) @RequestParam("password") String password,
                                     @Pattern (regexp = EMAIL_REGEX) @RequestParam("email") String email,
                                     @Length(min = 6,max = 6) @RequestParam("code") String code,
                                     HttpSession httpSession){
        String result = authorizeService.validateAndRegister(username,password,email,code,httpSession.getId());
        return RestInfo.success(result);
    }


    /**
     * 修改密码接口
     * 发送验证邮件,从redis中校验验证码是否正确
     * 验证码正确就往session回话中存入一个标记,表示这次回话验证通过了
     * 发起重置密码,如果session中存在标记就重置
     */
    @PostMapping("startResetPwd")
    public RestInfo<String> startResetPwd(@Pattern (regexp = EMAIL_REGEX) @RequestParam("email") String email,
                                      @Length(min = 6,max = 6) @RequestParam("code") String code,HttpSession httpSession){
        String result = authorizeService.validateEmailCode(email,code,httpSession);
        return RestInfo.success(result);
    }


    /**
     * 修改密码接口
     */
    @PostMapping("resetPassWord")
    public RestInfo<String> resetPassWord(@Length(min = 8,max = 16) @RequestParam("password") String password,
                                        HttpSession httpSession){
        String email = (String)httpSession.getAttribute("reset-password");
        if (email == null){
            return RestInfo.failure(400,"请先完成邮箱验证");
        }
        boolean flag = authorizeService.resetPassWord(password,email);
        if (flag){
            httpSession.removeAttribute("reset-password");
            return RestInfo.success("密码重置成功");
        }
        return RestInfo.failure(400,"服务器繁忙");
    }

}
